package com.hutu.erp.catalog.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.hutu.erp.catalog.dto.CategoryOutput;
import com.ruoyi.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.hutu.erp.catalog.mapper.CategoryMapper;
import com.hutu.erp.catalog.domain.Category;
import com.hutu.erp.catalog.service.ICategoryService;

/**
 * 商品分类Service业务层处理
 * 
 * @author ruoyi
 * @date 2021-05-24
 */
@Service
public class CategoryServiceImpl implements ICategoryService 
{
    @Autowired
    private CategoryMapper categoryMapper;

    /**
     * 查询商品分类
     * 
     * @param categoryId 商品分类ID
     * @return 商品分类
     */
    @Override
    public Category selectCategoryById(Long categoryId)
    {
        return categoryMapper.selectCategoryById(categoryId);
    }

    /**
     * 查询商品分类列表
     * 
     * @param category 商品分类
     * @return 商品分类
     */
    @Override
    public List<Category> selectCategoryList(Category category)
    {
        return categoryMapper.selectCategoryList(category);
    }

    /**
     * 新增商品分类
     * 
     * @param category 商品分类
     * @return 结果
     */
    @Override
    public int insertCategory(Category category)
    {
        System.out.println("输出一下 category，查看一下页面上采集到的数据。");
        System.out.println(category);
        category.setCreatedBy(SecurityUtils.getUsername());
        category.setUpdatedBy(SecurityUtils.getUsername());

        return categoryMapper.insertCategory(category);
    }

    /**
     * 修改商品分类
     * 
     * @param category 商品分类
     * @return 结果
     */
    @Override
    public int updateCategory(Category category)
    {
        return categoryMapper.updateCategory(category);
    }

    /**
     * 批量删除商品分类
     * 
     * @param categoryIds 需要删除的商品分类ID
     * @return 结果
     */
    @Override
    public int deleteCategoryByIds(Long[] categoryIds)
    {
        return categoryMapper.deleteCategoryByIds(categoryIds);
    }

    /**
     * 删除商品分类信息
     * 
     * @param categoryId 商品分类ID
     * @return 结果
     */
    @Override
    public int deleteCategoryById(Long categoryId)
    {
        return categoryMapper.deleteCategoryById(categoryId);
    }

    //@Cacheable(cacheNames = "category_all_tree", key = "'category_all_tree'")
    @Override
    public List<CategoryOutput> getCategoryTree() {
        List<CategoryOutput> categories = new ArrayList<CategoryOutput>();

        List<Category> list = categoryMapper.selectCategoryList(null);

        // List<CategoryOutput> root = new ArrayList<CategoryOutput>();
        List<Category> root = list.stream()
                .filter(c -> c.getParentId().equals(0L)) // categories.Where(p => p.ParentCategoryId == 0)
                .collect(Collectors.toList()); // Tolist

        // 遍历跟级节点
        for(Category category: root)
        {
            if( category.isHandled() )
            {
                continue;
            }
            CategoryOutput dto = new CategoryOutput(
                    category.getCategoryId(),
                    0L,
                    category.getCategoryName(),
                    category.getAlternativeName(),
                    category.getCategoryCode(),
                    category.getLookup(),
                    category.getDisplayOrder()
            );
            dto.setLevel(1);
            dto.setLeaf(true);
            // leaf  hasChildren

            categories.add(dto);
            category.setHandled(true);

            populateChildren(list.stream()
                    .filter(c -> !c.isHandled() ) // categories.Where(p => p.ParentCategoryId == 0)
                    .collect(Collectors.toList()), dto);
        }

        return categories;
    }

    private  void  populateChildren(List<Category> categories, CategoryOutput parent) {
        for(Category category: categories)
        {
            if( category.isHandled() )
            {
                continue;
            }
            if(category.getParentId().equals(parent.getCategoryId())) {
                CategoryOutput dto = new CategoryOutput(
                        category.getCategoryId(),
                        parent.getCategoryId(),
                        category.getCategoryName(),
                        category.getAlternativeName(),
                        category.getCategoryCode(),
                        category.getLookup(),
                        category.getDisplayOrder()
                );
                dto.setLeaf(true);
                dto.setLevel(parent.getLevel() + 1);

                String ancestors = parent.getAncestors();
                if(ancestors == null){
                    dto.setAncestors(parent.getCategoryId().toString());
                } else {
                    dto.setAncestors(ancestors + "," + parent.getCategoryId().toString());
                }
                List<CategoryOutput> children = parent.getChildren();
                if(children == null) {
                    children = new ArrayList<CategoryOutput>();
                    parent.setChildren(children);
                }
                parent.getChildren().add(dto);
                parent.setLeaf(false);
                parent.setHasChildren(true);

                category.setHandled(true);

                populateChildren(categories.stream()
                        .filter(c -> !c.isHandled() ) // categories.Where(p => p.ParentCategoryId == 0)
                        .collect(Collectors.toList()), dto);
            }
        }
    }

    @Override
    @Cacheable(cacheNames = "category_all", key = "'category_all'")
    public List<CategoryOutput> getAllCategories() {
        List<CategoryOutput> categories = new ArrayList<CategoryOutput>();
        List<Category> list = categoryMapper.selectCategoryList(null);
        for(Category category: list)
        {
            CategoryOutput dto = new CategoryOutput(
                    category.getCategoryId(),
                    0L,
                    category.getCategoryName(),
                    category.getAlternativeName(),
                    category.getCategoryCode(),
                    category.getLookup(),
                    category.getDisplayOrder()
            );
            categories.add(dto);

        }

        return categories;
    }
}
